package com.sec.android.app.myfiles.provider;

import android.net.Uri;

import com.sec.android.app.myfiles.module.ModuleLoader;
import com.sec.android.app.myfiles.module.abstraction.FileRecord.StorageType;

import java.util.ArrayList;

public abstract class DbTableInfo {

    public static final String COLUMN_NAME_SEF_FILE_TYPE = "sef_file_type";
    public static final String COLUMN_NAME_GEAR360_VIDEO = "is_360_video";
    public static final String EXT_QUERY = "LOWER ( replace( _display_name, rtrim( _display_name, replace (_display_name, '.', '' ) ), '') )";

    protected ArrayList<DB_Column> mTableColumn = new ArrayList<>();

    public enum COLUMN_ID {
        ID,
        MEDIA_ID,
        PATH,
        NAME,
        SIZE,
        DATE,
        FILE_TYPE,
        EXT,
        IS_DIRECTORY,
        MIME_TYPE,
        IS_HIDDEN,
        ITEM_COUNT,
        ITEM_COUNT_HIDDEN,
        FORMAT,
        /*Category*/
        BUCKET_ID,
        BUCKET_DISPLAY_NAME,
        /*Image category*/
        WIDTH,
        HEIGHT,
        /*Video category*/
        DURATION,
        RESUME_POS,
        /*Audio category*/
        ARTIST,
        ALBUM,
        /*For Cloud*/
        FILE_ID,
        DEVICE_ID,
        ALTERNATIVE_LINK,
        PARENT_CLOUD_ID,
        /*For download history*/
        DOWNLOAD_ID,
        SOURCE,
        DESCRIPTION,
        STATUS,
        DOWNLOAD_BY,
        DOWNLOADED_ITEM_VISIBILITY,
        FROM_S_BROWSER,
        /*For shortcut*/
        STORAGE_TYPE,
        SHORTCUT_TYPE,
        INTENT,
        /*For preview compress*/
        ARCHIVE_PATH,
        ARCHIVE_ID,
        /*For recent*/
        RECENT_DATE,
        /*Search*/
        PARENT,
        /*Folder tree*/
        OPENED,
        /*Gear360*/
        SEF_FILE_TYPE,
        IS_360_VIDEO,
        IS_360_CONTENTS,
        /*Optimize storage*/
        OPTIMIZE_TYPE,
        SUB_GROUP_ID,
        /*Cloud trash*/
        TRASH_PROCESSING,
        /*Get more space*/
        DATE_ACCESSED
    }

    public static final String QUERY_PARAM_LIMIT = "limit";
    public static final String QUERY_PARAM_NOTIFY_CHANGE = "notify_change";

    private Uri mUri;

    public String getUri() {
        //return "content://myfiles/" + getTableName();
        return "content://PrivateMyfiles/" + getTableName();
    }

    public Uri getUriInstance() {
        if (mUri == null) {
            mUri = Uri.parse(getUri());
        }
        return mUri;
    }

    public static class DB_Column {
        public DB_Column(COLUMN_ID id, String name, String attr) {
            init(id, name, attr, null);
        }

        public DB_Column(COLUMN_ID id, String name, String attr, String query) {
            init(id, name, attr, query);
        }

        protected void init(COLUMN_ID id, String name, String attr, String query) {
            mID = id;
            mName = name;
            mAttribute = attr;
            mQuery = query;
        }

        public COLUMN_ID mID;
        public String mName;
        public String mAttribute;
        public String mQuery;
    }

    public static DbTableInfo getInstance(StorageType storageType) {
        return ModuleLoader.getInstance().getTableInfo(storageType);
    }

    protected void removeColumnInfo(COLUMN_ID columnId) {
        for (DB_Column column : mTableColumn) {
            if (column.mID == columnId) {
                mTableColumn.remove(column);
                break;
            }
        }
    }

    public int getColumnCount() {
        return mTableColumn.size();
    }

    public COLUMN_ID getColumnID(int index) {
        return mTableColumn.get(index).mID;
    }

    public String getColumnName(COLUMN_ID columId) {
        String ret = null;
        for (DB_Column column : mTableColumn) {
            if (column.mID == columId) {
                ret = column.mName;
                break;
            }
        }

        return ret;
    }

    public String getColumnQuery(COLUMN_ID columId) {
        String ret = null;
        for (DB_Column column : mTableColumn) {
            if (column.mID == columId) {
                ret = column.mQuery;
                break;
            }
        }

        return ret;
    }

    public int getIndex(COLUMN_ID columId) {
        int ret = -1;
        int nIndex = 0;
        for (DB_Column column : mTableColumn) {
            if (column.mID == columId) {
                ret = nIndex;
                break;
            }
            nIndex++;
        }
        return ret;
    }

    public String getColumnAttr(COLUMN_ID columId) {
        String ret = null;
        for (DB_Column column : mTableColumn) {
            if (column.mID == columId) {
                ret = column.mAttribute;
                break;
            }
        }

        return ret;
    }

    public String[] getProjection() {
        ArrayList<String> projectionList = new ArrayList<>();

        for (int i = 0; i < getColumnCount(); i++) {
            COLUMN_ID col = getColumnID(i);
            if (getColumnAttr(col) != null) {
                projectionList.add(getColumnName(col));
            } else {
                projectionList.add(getColumnQuery(col));
            }
        }

        int size = projectionList.size();
        String[] ret = null;
        if (size > 0) {
            ret = projectionList.toArray(new String[size]);
        }
        return ret;
    }

    /**
     * <p>
     * Define table name it will be define provider URI
     * </p>
     * <p/>
     * If this name is sub-string of other table name, it will not work proper
     * <p/>
     *
     * @return table name
     */
    public abstract String getTableName();

    /**
     * <p>
     * Define that create real database.
     * </p>
     * <p/>
     * If it returns true, DB table is created as defined table info
     * <p/>
     *
     * @return true/false
     */
    public abstract boolean isRealDb();

}
